{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "37tFN3XcxyPc" }, "source": [ "# **Aula Machine Learning - Trainee GVCode**" ] }, { "cell_type": "markdown", "metadata": { "id": "dP-sIhXAxyPh" }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "id": "D3NPgIuHxyPi" }, "source": [ ">Machine Learning is making the computer learn from studying data and statistics.\n", ">\n", ">Machine Learning is a step into the direction of artificial intelligence (AI).\n", ">\n", ">Machine Learning is a program that analyses data and learns to predict the outcome." ] }, { "cell_type": "markdown", "metadata": { "id": "nMekDh3rxyPj" }, "source": [ "Esse guia será dividido em 2 partes principais que são essenciais para a criação de um modelo funcional e utilizável:\n", "\n", "1. Pré-processamento dos dados e análise exploratória\n", "\n", " 1.1. Carregamento dos dados\\\n", " 1.2. Limpeza dos dados\\\n", " 1.3. Análise exploratória\n", "\n", "2. Modelagem\n", "\n", " 2.1. Criação do modelo\\\n", " 2.2. Resultados\\\n", " 2.3. Validação do modelo" ] }, { "cell_type": "markdown", "metadata": { "id": "I0HfReNaxyPk" }, "source": [ "## **Parte 1 - Pré-processamento dos dados e análise exploratória** - Problema Supervisionado (A máquina vai ver os dados)" ] }, { "cell_type": "markdown", "metadata": { "id": "DLRqyw231YZN" }, "source": [ "### Pré-processamento" ] }, { "cell_type": "markdown", "metadata": { "id": "dY86oMXuxyPk" }, "source": [ "\n", "\n", "O pré-processamento é uma parte crucial que deve ser feita sempre no ínicio de um projeto de Data Science (ao menos que algúem tenha feito para você). Isso inclui:\n", "* Lidar com valores NULL, ou seja, sem valor\n", "* Remover colunas e linhas com informações irrelevantes\n", "* Detectar outliers\n", "* Limpar os dados em geral." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "KYt19bBqxyPl" }, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "O dataset pode ser encontrado no [Kaggle](https://www.kaggle.com/datasets/sujay1844/used-car-prices/data), e no [GitHub do trainee](../data/car_old.csv)." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "id": "Fm7sA20uxyPo", "outputId": "29d1bf4b-2cf6-4113-9f29-e08e159808ee" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Unnamed: 0NameLocationYearKilometers_DrivenFuel_TypeTransmissionOwner_TypeMileageEnginePowerSeatsNew_PricePrice
00Maruti Wagon R LXI CNGMumbai201072000CNGManualFirst26.6 km/kg998 CC58.16 bhp5.0NaN1.75
11Hyundai Creta 1.6 CRDi SX OptionPune201541000DieselManualFirst19.67 kmpl1582 CC126.2 bhp5.0NaN12.50
22Honda Jazz VChennai201146000PetrolManualFirst18.2 kmpl1199 CC88.7 bhp5.08.61 Lakh4.50
33Maruti Ertiga VDIChennai201287000DieselManualFirst20.77 kmpl1248 CC88.76 bhp7.0NaN6.00
44Audi A4 New 2.0 TDI MultitronicCoimbatore201340670DieselAutomaticSecond15.2 kmpl1968 CC140.8 bhp5.0NaN17.74
\n", "
" ], "text/plain": [ " Unnamed: 0 Name Location Year \\\n", "0 0 Maruti Wagon R LXI CNG Mumbai 2010 \n", "1 1 Hyundai Creta 1.6 CRDi SX Option Pune 2015 \n", "2 2 Honda Jazz V Chennai 2011 \n", "3 3 Maruti Ertiga VDI Chennai 2012 \n", "4 4 Audi A4 New 2.0 TDI Multitronic Coimbatore 2013 \n", "\n", " Kilometers_Driven Fuel_Type Transmission Owner_Type Mileage Engine \\\n", "0 72000 CNG Manual First 26.6 km/kg 998 CC \n", "1 41000 Diesel Manual First 19.67 kmpl 1582 CC \n", "2 46000 Petrol Manual First 18.2 kmpl 1199 CC \n", "3 87000 Diesel Manual First 20.77 kmpl 1248 CC \n", "4 40670 Diesel Automatic Second 15.2 kmpl 1968 CC \n", "\n", " Power Seats New_Price Price \n", "0 58.16 bhp 5.0 NaN 1.75 \n", "1 126.2 bhp 5.0 NaN 12.50 \n", "2 88.7 bhp 5.0 8.61 Lakh 4.50 \n", "3 88.76 bhp 7.0 NaN 6.00 \n", "4 140.8 bhp 5.0 NaN 17.74 " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# importing dataset\n", "car_train = pd.read_csv('car_train.csv')\n", "\n", "# printing the first 5 rows of dataset\n", "car_train.head()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "id": "tAc6ogO_xyPs", "outputId": "d08f26fc-a5ea-405f-8e93-46dea6acc758" }, "outputs": [ { "data": { "text/plain": [ "['Unnamed: 0',\n", " 'Name',\n", " 'Location',\n", " 'Year',\n", " 'Kilometers_Driven',\n", " 'Fuel_Type',\n", " 'Transmission',\n", " 'Owner_Type',\n", " 'Mileage',\n", " 'Engine',\n", " 'Power',\n", " 'Seats',\n", " 'New_Price',\n", " 'Price']" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# getting the columns of the dataset\n", "columns = list(car_train.columns)\n", "columns" ] }, { "cell_type": "markdown", "metadata": { "id": "IusdUm-YxyPu" }, "source": [ "Identifique e anote potenciais problemas que você terá que lidar no DataFrame:\n", "\n", "* Estão faltam valores em algumas colunas (NaN). Isso poderá causar muitos problemas para a análise e modelagem se não resolvido no início do processo.\n", "\n", "* Algumas colunas possuem palavras e números, como o mileage, engine e power. Isso pode ser um problema se a gente quiser montar um gráfico de time-series (evolução dos dados ao longo do tempo) pela data ou outros gráficos para explorar a relação da duration com outras variáveis.\n", "\n", "* Existem diversas colunas com os strings que devem ser transformadas em dummies para que o modelo possa ser treinado." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "id": "ku4cm4PixyPv", "outputId": "7160d037-627a-48d0-e214-d6da0d1b42c9" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Missing values distribution: \n", "Unnamed: 0 0\n", "Name 0\n", "Location 0\n", "Year 0\n", "Kilometers_Driven 0\n", "Fuel_Type 0\n", "Transmission 0\n", "Owner_Type 0\n", "Mileage 2\n", "Engine 36\n", "Power 36\n", "Seats 42\n", "New_Price 5195\n", "Price 0\n", "dtype: int64\n", "\n" ] } ], "source": [ "# examining missing values - Quantidades de valores ausentes em cada coluna \n", "print(\"Missing values distribution: \")\n", "print(car_train.isna().sum())\n", "print(\"\")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "id": "5HrnrA96xyPw", "outputId": "7d439fb7-d0d2-4ce4-dc54-5df6055b7065" }, "outputs": [ { "data": { "text/plain": [ "(6019, 14)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# O tamanho do nosso DataFrame - Linhas e Colunas \n", "\n", "car_train.shape" ] }, { "cell_type": "markdown", "metadata": { "id": "bvv-7I3jxyPy" }, "source": [ "Como lidar com os valores nulos nas colunas?\n", "\n", "Existem algumas formas para resolver esse problema:\n", "\n", "1. Dropar a coluna inteira. Se a coluna não for muito importante ou tiver pouquíssimos dados, simplesmente a remova.\n", "\n", "2. Continue com a coluna, caso ela seja importante.\n", "\n", "3. Substituir os valores valores nulos por outros de forma que não interfira na análise. (Ex: foward fill, backwards fill, média, etc)\n", "\n", "Foward fill -> o último valor conhecido é usado como referência \n", "\n", "Backward fill -> O valor seguinté é usado como referência para os anteriores \n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "id": "yYpAQVYNxyPz" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameLocationYearKilometers_DrivenFuel_TypeTransmissionOwner_TypeMileageEnginePowerSeatsPrice
0Maruti Wagon R LXI CNGMumbai201072000CNGManualFirst26.6 km/kg998 CC58.16 bhp5.01.75
1Hyundai Creta 1.6 CRDi SX OptionPune201541000DieselManualFirst19.67 kmpl1582 CC126.2 bhp5.012.50
2Honda Jazz VChennai201146000PetrolManualFirst18.2 kmpl1199 CC88.7 bhp5.04.50
3Maruti Ertiga VDIChennai201287000DieselManualFirst20.77 kmpl1248 CC88.76 bhp7.06.00
4Audi A4 New 2.0 TDI MultitronicCoimbatore201340670DieselAutomaticSecond15.2 kmpl1968 CC140.8 bhp5.017.74
.......................................
6014Maruti Swift VDIDelhi201427365DieselManualFirst28.4 kmpl1248 CC74 bhp5.04.75
6015Hyundai Xcent 1.1 CRDi SJaipur2015100000DieselManualFirst24.4 kmpl1120 CC71 bhp5.04.00
6016Mahindra Xylo D4 BSIVJaipur201255000DieselManualSecond14.0 kmpl2498 CC112 bhp8.02.90
6017Maruti Wagon R VXIKolkata201346000PetrolManualFirst18.9 kmpl998 CC67.1 bhp5.02.65
6018Chevrolet Beat DieselHyderabad201147000DieselManualFirst25.44 kmpl936 CC57.6 bhp5.02.50
\n", "

5975 rows × 12 columns

\n", "
" ], "text/plain": [ " Name Location Year Kilometers_Driven \\\n", "0 Maruti Wagon R LXI CNG Mumbai 2010 72000 \n", "1 Hyundai Creta 1.6 CRDi SX Option Pune 2015 41000 \n", "2 Honda Jazz V Chennai 2011 46000 \n", "3 Maruti Ertiga VDI Chennai 2012 87000 \n", "4 Audi A4 New 2.0 TDI Multitronic Coimbatore 2013 40670 \n", "... ... ... ... ... \n", "6014 Maruti Swift VDI Delhi 2014 27365 \n", "6015 Hyundai Xcent 1.1 CRDi S Jaipur 2015 100000 \n", "6016 Mahindra Xylo D4 BSIV Jaipur 2012 55000 \n", "6017 Maruti Wagon R VXI Kolkata 2013 46000 \n", "6018 Chevrolet Beat Diesel Hyderabad 2011 47000 \n", "\n", " Fuel_Type Transmission Owner_Type Mileage Engine Power Seats \\\n", "0 CNG Manual First 26.6 km/kg 998 CC 58.16 bhp 5.0 \n", "1 Diesel Manual First 19.67 kmpl 1582 CC 126.2 bhp 5.0 \n", "2 Petrol Manual First 18.2 kmpl 1199 CC 88.7 bhp 5.0 \n", "3 Diesel Manual First 20.77 kmpl 1248 CC 88.76 bhp 7.0 \n", "4 Diesel Automatic Second 15.2 kmpl 1968 CC 140.8 bhp 5.0 \n", "... ... ... ... ... ... ... ... \n", "6014 Diesel Manual First 28.4 kmpl 1248 CC 74 bhp 5.0 \n", "6015 Diesel Manual First 24.4 kmpl 1120 CC 71 bhp 5.0 \n", "6016 Diesel Manual Second 14.0 kmpl 2498 CC 112 bhp 8.0 \n", "6017 Petrol Manual First 18.9 kmpl 998 CC 67.1 bhp 5.0 \n", "6018 Diesel Manual First 25.44 kmpl 936 CC 57.6 bhp 5.0 \n", "\n", " Price \n", "0 1.75 \n", "1 12.50 \n", "2 4.50 \n", "3 6.00 \n", "4 17.74 \n", "... ... \n", "6014 4.75 \n", "6015 4.00 \n", "6016 2.90 \n", "6017 2.65 \n", "6018 2.50 \n", "\n", "[5975 rows x 12 columns]" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#drop the column with the missing values - Eliminando a Coluna New Price e Unnamed\n", "car_train.drop(['New_Price', 'Unnamed: 0'], inplace=True, axis= 1) # inplace = True(não vai criar um novo dataFrame) / axis = 1 (especificando uma coluna)\n", "car_train.dropna(inplace=True, axis=0) #Removendo todas as linhas que contenham pelo menos um valor NaN\n", "car_train" ] }, { "cell_type": "markdown", "metadata": { "id": "eawU-0vjxyP0" }, "source": [ "Agora é preciso lidar com as colunas que contém números e strings, que vão atrapalhar na hora de fazer a modelagem. Primeiro vamos verificar o tipo das observações em cada coluna:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "5dSqdFRAxyP1", "outputId": "8cdc352a-a179-43c5-9e2d-9ffed23f1b08" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Column datatypes: \n", "Name object\n", "Location object\n", "Year int64\n", "Kilometers_Driven int64\n", "Fuel_Type object\n", "Transmission object\n", "Owner_Type object\n", "Mileage object\n", "Engine object\n", "Power object\n", "Seats float64\n", "Price float64\n", "dtype: object\n" ] } ], "source": [ "# check datatype in each column\n", "print(\"Column datatypes: \")\n", "print(car_train.dtypes)" ] }, { "cell_type": "markdown", "metadata": { "id": "JmlbrnzpxyP2" }, "source": [ "Como podemos ver, as colunas Mileage, Engine e Power, que deveriam estar em int ou float, estão em string. Para arrumar isso:\n", "\n", "1. Tirar as unidades de medida de todas as observações\n", "2. Transformar a coluna em tipo numérico (int ou float)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "id": "GGVXdMKBxyP2", "outputId": "04af7825-4ca0-4fd4-a36b-e0542d387597" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameLocationYearKilometers_DrivenFuel_TypeTransmissionOwner_TypeMileageEnginePowerSeatsPrice
0Maruti Wagon R LXI CNGMumbai201072000CNGManualFirst26.60998.058.165.01.75
1Hyundai Creta 1.6 CRDi SX OptionPune201541000DieselManualFirst19.671582.0126.205.012.50
2Honda Jazz VChennai201146000PetrolManualFirst18.201199.088.705.04.50
3Maruti Ertiga VDIChennai201287000DieselManualFirst20.771248.088.767.06.00
4Audi A4 New 2.0 TDI MultitronicCoimbatore201340670DieselAutomaticSecond15.201968.0140.805.017.74
.......................................
6014Maruti Swift VDIDelhi201427365DieselManualFirst28.401248.074.005.04.75
6015Hyundai Xcent 1.1 CRDi SJaipur2015100000DieselManualFirst24.401120.071.005.04.00
6016Mahindra Xylo D4 BSIVJaipur201255000DieselManualSecond14.002498.0112.008.02.90
6017Maruti Wagon R VXIKolkata201346000PetrolManualFirst18.90998.067.105.02.65
6018Chevrolet Beat DieselHyderabad201147000DieselManualFirst25.44936.057.605.02.50
\n", "

5872 rows × 12 columns

\n", "
" ], "text/plain": [ " Name Location Year Kilometers_Driven \\\n", "0 Maruti Wagon R LXI CNG Mumbai 2010 72000 \n", "1 Hyundai Creta 1.6 CRDi SX Option Pune 2015 41000 \n", "2 Honda Jazz V Chennai 2011 46000 \n", "3 Maruti Ertiga VDI Chennai 2012 87000 \n", "4 Audi A4 New 2.0 TDI Multitronic Coimbatore 2013 40670 \n", "... ... ... ... ... \n", "6014 Maruti Swift VDI Delhi 2014 27365 \n", "6015 Hyundai Xcent 1.1 CRDi S Jaipur 2015 100000 \n", "6016 Mahindra Xylo D4 BSIV Jaipur 2012 55000 \n", "6017 Maruti Wagon R VXI Kolkata 2013 46000 \n", "6018 Chevrolet Beat Diesel Hyderabad 2011 47000 \n", "\n", " Fuel_Type Transmission Owner_Type Mileage Engine Power Seats Price \n", "0 CNG Manual First 26.60 998.0 58.16 5.0 1.75 \n", "1 Diesel Manual First 19.67 1582.0 126.20 5.0 12.50 \n", "2 Petrol Manual First 18.20 1199.0 88.70 5.0 4.50 \n", "3 Diesel Manual First 20.77 1248.0 88.76 7.0 6.00 \n", "4 Diesel Automatic Second 15.20 1968.0 140.80 5.0 17.74 \n", "... ... ... ... ... ... ... ... ... \n", "6014 Diesel Manual First 28.40 1248.0 74.00 5.0 4.75 \n", "6015 Diesel Manual First 24.40 1120.0 71.00 5.0 4.00 \n", "6016 Diesel Manual Second 14.00 2498.0 112.00 8.0 2.90 \n", "6017 Petrol Manual First 18.90 998.0 67.10 5.0 2.65 \n", "6018 Diesel Manual First 25.44 936.0 57.60 5.0 2.50 \n", "\n", "[5872 rows x 12 columns]" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#replace with blank and transform to float\n", "car_train['Mileage'] = car_train['Mileage'].str.replace('kmpl', '').str.replace('km/kg', '')\n", "car_train['Engine'] = car_train['Engine'].str.replace('CC', '')\n", "car_train['Power'] = car_train['Power'].str.replace('bhp', '')\n", "\n", "col = ['Mileage','Engine','Power'] # Lista com o nome das colunas que serão convertidas em números \n", "\n", "car_train[col] = car_train[col].apply(pd.to_numeric, errors= 'coerce',axis=1) #errors = \"coerce\" (se ocorrer algum erro, os valores serão definidos como Nan)\n", "\n", "# raise (padrão) = o processo é interrompido \n", "# ignore = ignora o erro \n", "# [\"raise\", \"coerce\"] -> Podemos usar em formato de lista, dessa forma podemos controlar o comportamentos de diferentes colunas \n", "\n", "car_train.dropna(inplace=True, axis=0) # Removendo os NaN novamente \n", "\n", "car_train" ] }, { "cell_type": "markdown", "metadata": { "id": "z8X0OKKWxyP3" }, "source": [ "Agora que resolvemos com as colunas que tinham valores em strings e numéricos, precisamos transformar em código as colunas com dados categóricos (Name, Location, Fuel_Type, Transmission):" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "id": "wj9DskJOxyP3" }, "outputs": [], "source": [ "from sklearn import preprocessing" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "id": "xl8sreurxyP3", "outputId": "f68388a0-5b7c-4fcc-ffcf-6b7d94936d7e" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameLocationYearKilometers_DrivenFuel_TypeTransmissionOwner_TypeMileageEnginePowerSeatsPrice
0Maruti Wagon R LXI CNG920107200001126.60998.058.165.01.75
1Hyundai Creta 1.6 CRDi SX Option1020154100011119.671582.0126.205.012.50
2Honda Jazz V220114600031118.201199.088.705.04.50
3Maruti Ertiga VDI220128700011120.771248.088.767.06.00
4Audi A4 New 2.0 TDI Multitronic320134067010215.201968.0140.805.017.74
.......................................
6014Maruti Swift VDI420142736511128.401248.074.005.04.75
6015Hyundai Xcent 1.1 CRDi S6201510000011124.401120.071.005.04.00
6016Mahindra Xylo D4 BSIV620125500011214.002498.0112.008.02.90
6017Maruti Wagon R VXI820134600031118.90998.067.105.02.65
6018Chevrolet Beat Diesel520114700011125.44936.057.605.02.50
\n", "

5872 rows × 12 columns

\n", "
" ], "text/plain": [ " Name Location Year Kilometers_Driven \\\n", "0 Maruti Wagon R LXI CNG 9 2010 72000 \n", "1 Hyundai Creta 1.6 CRDi SX Option 10 2015 41000 \n", "2 Honda Jazz V 2 2011 46000 \n", "3 Maruti Ertiga VDI 2 2012 87000 \n", "4 Audi A4 New 2.0 TDI Multitronic 3 2013 40670 \n", "... ... ... ... ... \n", "6014 Maruti Swift VDI 4 2014 27365 \n", "6015 Hyundai Xcent 1.1 CRDi S 6 2015 100000 \n", "6016 Mahindra Xylo D4 BSIV 6 2012 55000 \n", "6017 Maruti Wagon R VXI 8 2013 46000 \n", "6018 Chevrolet Beat Diesel 5 2011 47000 \n", "\n", " Fuel_Type Transmission Owner_Type Mileage Engine Power Seats \\\n", "0 0 1 1 26.60 998.0 58.16 5.0 \n", "1 1 1 1 19.67 1582.0 126.20 5.0 \n", "2 3 1 1 18.20 1199.0 88.70 5.0 \n", "3 1 1 1 20.77 1248.0 88.76 7.0 \n", "4 1 0 2 15.20 1968.0 140.80 5.0 \n", "... ... ... ... ... ... ... ... \n", "6014 1 1 1 28.40 1248.0 74.00 5.0 \n", "6015 1 1 1 24.40 1120.0 71.00 5.0 \n", "6016 1 1 2 14.00 2498.0 112.00 8.0 \n", "6017 3 1 1 18.90 998.0 67.10 5.0 \n", "6018 1 1 1 25.44 936.0 57.60 5.0 \n", "\n", " Price \n", "0 1.75 \n", "1 12.50 \n", "2 4.50 \n", "3 6.00 \n", "4 17.74 \n", "... ... \n", "6014 4.75 \n", "6015 4.00 \n", "6016 2.90 \n", "6017 2.65 \n", "6018 2.50 \n", "\n", "[5872 rows x 12 columns]" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cols = ['Location', 'Fuel_Type', 'Transmission'] # Listta das colunas que queremos alterar \n", "\n", "car_train[cols] = car_train[cols].apply(preprocessing.LabelEncoder().fit_transform) # LabelEncoder -> ferramenta para transformar rótulos categóricos em valores numéricos\n", "\n", "car_train" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "id": "pr6BiBY6xyP4", "outputId": "f5efe85c-78d7-404a-9654-bbc22322861f" }, "outputs": [ { "data": { "text/plain": [ "array([1, 2, 4, 3], dtype=int64)" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "car_train.Owner_Type.unique() #valores ordinais (não métrico)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "id": "4SNqTJa9xyP5" }, "outputs": [], "source": [ "owner = {'First':1,'Second':2, 'Third':3,'Fourth & Above':4}\n", "\n", "car_train.Owner_Type = car_train.Owner_Type.replace(owner)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "id": "Pfriz8kuxyP5", "outputId": "04d8f544-999b-4f4c-d5ca-59372cd08ccf" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameLocationYearKilometers_DrivenFuel_TypeTransmissionOwner_TypeMileageEnginePowerSeatsPrice
0Maruti Wagon R LXI CNG920107200001126.60998.058.165.01.75
1Hyundai Creta 1.6 CRDi SX Option1020154100011119.671582.0126.205.012.50
2Honda Jazz V220114600031118.201199.088.705.04.50
3Maruti Ertiga VDI220128700011120.771248.088.767.06.00
4Audi A4 New 2.0 TDI Multitronic320134067010215.201968.0140.805.017.74
.......................................
6014Maruti Swift VDI420142736511128.401248.074.005.04.75
6015Hyundai Xcent 1.1 CRDi S6201510000011124.401120.071.005.04.00
6016Mahindra Xylo D4 BSIV620125500011214.002498.0112.008.02.90
6017Maruti Wagon R VXI820134600031118.90998.067.105.02.65
6018Chevrolet Beat Diesel520114700011125.44936.057.605.02.50
\n", "

5872 rows × 12 columns

\n", "
" ], "text/plain": [ " Name Location Year Kilometers_Driven \\\n", "0 Maruti Wagon R LXI CNG 9 2010 72000 \n", "1 Hyundai Creta 1.6 CRDi SX Option 10 2015 41000 \n", "2 Honda Jazz V 2 2011 46000 \n", "3 Maruti Ertiga VDI 2 2012 87000 \n", "4 Audi A4 New 2.0 TDI Multitronic 3 2013 40670 \n", "... ... ... ... ... \n", "6014 Maruti Swift VDI 4 2014 27365 \n", "6015 Hyundai Xcent 1.1 CRDi S 6 2015 100000 \n", "6016 Mahindra Xylo D4 BSIV 6 2012 55000 \n", "6017 Maruti Wagon R VXI 8 2013 46000 \n", "6018 Chevrolet Beat Diesel 5 2011 47000 \n", "\n", " Fuel_Type Transmission Owner_Type Mileage Engine Power Seats \\\n", "0 0 1 1 26.60 998.0 58.16 5.0 \n", "1 1 1 1 19.67 1582.0 126.20 5.0 \n", "2 3 1 1 18.20 1199.0 88.70 5.0 \n", "3 1 1 1 20.77 1248.0 88.76 7.0 \n", "4 1 0 2 15.20 1968.0 140.80 5.0 \n", "... ... ... ... ... ... ... ... \n", "6014 1 1 1 28.40 1248.0 74.00 5.0 \n", "6015 1 1 1 24.40 1120.0 71.00 5.0 \n", "6016 1 1 2 14.00 2498.0 112.00 8.0 \n", "6017 3 1 1 18.90 998.0 67.10 5.0 \n", "6018 1 1 1 25.44 936.0 57.60 5.0 \n", "\n", " Price \n", "0 1.75 \n", "1 12.50 \n", "2 4.50 \n", "3 6.00 \n", "4 17.74 \n", "... ... \n", "6014 4.75 \n", "6015 4.00 \n", "6016 2.90 \n", "6017 2.65 \n", "6018 2.50 \n", "\n", "[5872 rows x 12 columns]" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "car_train" ] }, { "cell_type": "markdown", "metadata": { "id": "LT5TZyTxyYi0" }, "source": [ "### Análise exploratória" ] }, { "cell_type": "markdown", "metadata": { "id": "mGXH4gKSxyP5" }, "source": [ "Com a nossa base de dados completamente limpa, vamos analisar a correlação entre as variáveis que vamos colocar no modelo de forma a aumentar sua acurácia.\n", "\n", "\n", "\n", "Existem diferentes testes para diferentes situações, dependendo do tipo das variáveis." ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "id": "vUbDvgeBxyP6", "outputId": "76653453-2172-4958-c01b-35bf6aa9ed67" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\filip\\AppData\\Local\\Temp\\ipykernel_12856\\637126045.py:2: FutureWarning: The default value of numeric_only in DataFrame.corr is deprecated. In a future version, it will default to False. Select only valid columns or specify the value of numeric_only to silence this warning.\n", " car_train.corr(method='pearson')['Price'] # Correlação das variáveis com o preço, quanto mais próximo de 1, maior a correlação entre as variáveis\n" ] }, { "data": { "text/plain": [ "Location -0.118238\n", "Year 0.299475\n", "Kilometers_Driven -0.008249\n", "Fuel_Type -0.301626\n", "Transmission -0.585623\n", "Owner_Type -0.091098\n", "Mileage -0.341652\n", "Engine 0.658047\n", "Power 0.772843\n", "Seats 0.055547\n", "Price 1.000000\n", "Name: Price, dtype: float64" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#Análise do correlograma\n", "car_train.corr(method='pearson')['Price'] # Correlação das variáveis com o preço, quanto mais próximo de 1, maior a correlação entre as variáveis \n", "# Pelo que tivemos de retorno ( Transmissão), não faz sentido a relação de uma variável categórica com uma contínua \n", "# Correlação negativa - sentidos negativos (ex: mais donos menor o preço )" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "id": "CcjgDdvrxyP6", "outputId": "a9d8fb53-9985-48df-b91c-ee1553e8da59" }, "outputs": [ { "data": { "image/png": "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Sm1gvMEwDNP1FotF7du3V2xsrC5duqQjR47oiSeeUGZmpo4ePaq4uDi1aNFCZcv+/7+9JCgoSF5eXrb5gIAAnTt3TpJ04sQJ/f777+ratas8PT1t04oVK5SUlGR37ubNm99xf25ubho2bJiWLVsmSfr222916NAhhYeH220XGhp603xiYqIkKSEhQRkZGapQoYJdzcnJyTfVfENERITS0tJs06lTp+64FwAAUDyV2pdeatWqJYvFosTERPXr1++m9YmJiSpXrpwqVaqksLAwvfvuu/rqq6/UrFkzeXt720JkXFycOnToYLdvmTJl7OYtFouys7MlSRkZGZKkzz//XFWqVLHbzmq12s17eHjccZ/S9dvSTZs21enTpxUVFaVOnTqpWrVqud4/IyNDAQEBttvwf+br63vLfaxW6039AACA0qnUjjBWqFBBXbt21VtvvaXLly/brTt79qxWrlypgQMHymKx2J5jXLNmje1ZxbCwMG3btk07d+7M08fW1K9fX1arVampqapVq5bdVFi3bRs1aqTmzZtryZIlWrVqlUaOHHnTNl9//fVN8zdu14eEhOjs2bNycXG5qeaKFSsWSs0AAKDkKLWBUZLeeOMNZWZmqlu3bvryyy916tQpbd68WV27dlWVKlX0/PPPS5IaN26scuXKadWqVXaBcd26dcrMzFSbNm1yfU4vLy9NmTJFEydO1Pvvv6+kpCR9++23ev311/X+++8XRpuSro8yzp8/X4Zh3HJEdefOnXrxxRf1v//9T2+++abWrFmj8ePHS7r+FnhoaKj69u2rrVu3KiUlRbt27dL06dO1b9++QqsZAACUDKU6MAYHB2vfvn2qUaOGBgwYoJo1a2r06NHq2LGjdu/ebXvRxGKxqF27drJYLGrbtq2k6yHS29tbzZs3z/Ot47lz52rmzJmKjIxUvXr11L17d33++eeqXr16gfd4w+DBg+Xi4qLBgwfLzc3tpvWTJ0/Wvn371KxZMz333HN65ZVX1K1bN0nX+9+4caPat2+vESNGqHbt2ho0aJBOnjwpPz+/QqsZAACUDBbjdm+FoERISUlRzZo1tXfvXoWEhNitCwoK0oQJEzRhwoRCO396evr1t6UnfCwna9nb75CDlPm9CrAqAABg5sbP77S0NHl7e+e4Xal96eVucfXqVV24cEEzZszQ3/72t5vCIgAAwJ0q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CvR3SQMAAKD0ITAWoD9/dM1fp6+++srR5QEAAOQLv5S4AMXHx+e4rkqVKkVXiAMdmtPNdEgbAACUPATGAlSrVi1HlwAAAFDguCUNAAAAUwRGAAAAmCIwAgAAwBSBEQAAAKYIjAAAADBFYAQAAIApAiMAAABMERgBAABgisAIAAAAUwRGAAAAmCIwAgAAwBSBEQAAAKYIjAAAADBFYAQAAIApAiMAAABMERgBAABgisAIAAAAUy6OLgClS8NZW+RkLevoMlDKpMzv5egSAOCuxggjAAAATBEYAQAAYIrACAAAAFMERgAAAJgiMJYwhmGoS5cu6tat203r3nrrLfn6+ur06dMOqAwAAJRWBMYSxmKxKCoqSt98840WL15sW56cnKynn35ar7/+uu69994CPefVq1cL9HgAAKBkITCWQIGBgXr11Vc1ZcoUJScnyzAMPfbYY/r73/+uZs2aqUePHvL09JSfn5+GDRum8+fP2/bdvHmz2rZtK19fX1WoUEH333+/kpKSbOtTUlJksVj00UcfqUOHDnJzc9PKlSsd0SYAACgmCIwl1KOPPqrOnTtr5MiReuONN3To0CEtXrxYnTp1UrNmzbRv3z5t3rxZP/30kwYMGGDb77ffftOkSZO0b98+xcTEyMnJSf369VN2drbd8adNm6bx48crMTHxlre/MzMzlZ6ebjcBAIDSyWIYhuHoIpA/586dU4MGDXTx4kV98sknOnTokL766itt2bLFts3p06cVGBioY8eOqXbt2jcd4/z586pUqZIOHjyohg0bKiUlRdWrV9eiRYs0fvz4HM89e/ZszZkz56blgRM+5oO7UeD44G4AKBzp6eny8fFRWlqavL29c9yOEcYS7J577tGYMWNUr1499e3bVwkJCdq+fbs8PT1tU926dSXJdtv5+PHjGjx4sGrUqCFvb28FBQVJklJTU+2O3bx5c9NzR0REKC0tzTadOnWq4BsEAADFAr8asIRzcXGRi8v1b2NGRoZ69+6tF1544abtAgICJEm9e/dWtWrVtGTJElWuXFnZ2dlq2LChrly5Yre9h4eH6XmtVqusVmsBdQEAAIozAmMpEhISok8++URBQUG2EPlnFy5c0LFjx7RkyRK1a9dOkrRjx46iLhMAAJQw3JIuRcaOHauLFy9q8ODB2rt3r5KSkrRlyxaNGDFCWVlZKleunCpUqKB3331XJ06c0H//+19NmjTJ0WUDAIBijsBYilSuXFk7d+5UVlaW/v73v6tRo0aaMGGCfH195eTkJCcnJ61evVr79+9Xw4YNNXHiRL300kuOLhsAABRzvCWNAnHjLSvekkZh4C1pACgcvCUNAACAAkFgBAAAgCnekkaBOjSnm+mQNgAAKHkYYQQAAIApAiMAAABMERgBAABgisAIAAAAUwRGAAAAmCIwAgAAwBSBEQAAAKYIjAAAADBFYAQAAIApAiMAAABMERgBAABgisAIAAAAUwRGAAAAmCIwAgAAwBSBEQAAAKYIjAAAADBFYAQAAIApAiMAAABMuTi6AJQuDWdtkZO1rKPLQA5S5vdydAkAgBKIEUYAAACYIjACAADAFIERAAAApgiMpZDFYtG6descXQYAACglCIx3KDw8XH379nXIuWfPnq2mTZvetPzMmTPq0aNH0RcEAABKJd6SLoX8/f0dXQIAAChFGGEsRHFxcWrZsqWsVqsCAgI0bdo0Xbt2zbY+OztbL774omrVqiWr1aqqVavq+eeft62fOnWqateurbJly6pGjRqaOXOmrl69Kklavny55syZo4SEBFksFlksFi1fvlzSzbekDx48qE6dOsnd3V0VKlTQ6NGjlZGRYVt/Y5R0wYIFCggIUIUKFTR27FjbuQAAwN2NEcZC8sMPP6hnz54KDw/XihUrdPToUT3++ONyc3PT7NmzJUkRERFasmSJFi5cqLZt2+rMmTM6evSo7RheXl5avny5KleurIMHD+rxxx+Xl5eXnn76aQ0cOFCHDh3S5s2btW3bNkmSj4/PTXX89ttv6tatm0JDQ7V3716dO3dOo0aN0rhx42wBU5K2b9+ugIAAbd++XSdOnNDAgQPVtGlTPf7447fsLzMzU5mZmbb59PT0ArhqAACgOCIwFpK33npLgYGBeuONN2SxWFS3bl39+OOPmjp1qv7973/rt99+06uvvqo33nhDjz76qCSpZs2aatu2re0YM2bMsH0dFBSkKVOmaPXq1Xr66afl7u4uT09Pubi4mN6CXrVqlf744w+tWLFCHh4ekqQ33nhDvXv31gsvvCA/Pz9JUrly5fTGG2/I2dlZdevWVa9evRQTE5NjYIyMjNScOXPu+DoBAIDij1vShSQxMVGhoaGyWCy2ZW3atFFGRoZOnz6txMREZWZmqnPnzjke46OPPlKbNm3k7+8vT09PzZgxQ6mpqXmuo0mTJraweKOO7OxsHTt2zLasQYMGcnZ2ts0HBATo3LlzOR43IiJCaWlptunUqVN5qgsAAJQcBEYHcXd3N12/e/duDRkyRD179tSGDRt04MABTZ8+XVeuXCmUesqUKWM3b7FYlJ2dneP2VqtV3t7edhMAACidCIyFpF69etq9e7cMw7At27lzp7y8vHTvvfcqODhY7u7uiomJueX+u3btUrVq1TR9+nQ1b95cwcHBOnnypN02rq6uysrKum0dCQkJ+u233+zqcHJyUp06de6gQwAAcLcgMBaAtLQ0xcfH202jR4/WqVOn9OSTT+ro0aP67LPPNGvWLE2aNElOTk5yc3PT1KlT9fTTT2vFihVKSkrS119/rffee0+SFBwcrNTUVK1evVpJSUl67bXX9Omnn9qdNygoSMnJyYqPj9f58+ftXkK5YciQIXJzc9Ojjz6qQ4cOafv27XryySc1bNgw2/OLAAAAZnjppQDExsaqWbNmdssee+wxbdy4UU899ZSaNGmi8uXL67HHHrN7kWXmzJlycXHRv//9b/34448KCAjQP/7xD0nSAw88oIkTJ2rcuHHKzMxUr169NHPmTNsb1pL00EMPKTo6Wh07dtSlS5cUFRWl8PBwuzrKli2rLVu2aPz48WrRooXKli2rhx56SK+88kqhXQ8AAFC6WIw/3zMF8ik9PV0+Pj4KnPCxnKxlHV0OcpAyv5ejSwAAFCM3fn6npaWZvo/ALWkAAACYIjACAADAFM8wokAdmtONj9gBAKCUYYQRAAAApgiMAAAAMEVgBAAAgCkCIwAAAEwRGAEAAGCKwAgAAABTBEYAAACY4nMYUSBu/IbJ9PR0B1cCAABy68bP7dv9pmgCIwrEhQsXJEmBgYEOrgQAAOTVr7/+Kh8fnxzXExhRIMqXLy9JSk1NNf0DV9Klp6crMDBQp06dKvW/0eZu6fVu6VO6e3q9W/qU7p5e75Y+paLv1TAM/frrr6pcubLpdgRGFAgnp+uPw/r4+JT6v8yS5O3tfVf0Kd09vd4tfUp3T693S5/S3dPr3dKnVLS95magh5deAAAAYIrACAAAAFMERhQIq9WqWbNmyWq1OrqUQnW39CndPb3eLX1Kd0+vd0uf0t3T693Sp1R8e7UYt3uPGgAAAHc1RhgBAABgisAIAAAAUwRGAAAAmCIwAgAAwBSBEbn25ptvKigoSG5ubmrVqpX27Nljuv2aNWtUt25dubm5qVGjRtq4cWMRVXpn8tLn4cOH9dBDDykoKEgWi0WLFi0qukILQF56XbJkidq1a6dy5cqpXLly6tKly23/DBQXeekzOjpazZs3l6+vrzw8PNS0aVN98MEHRVjtncnr39MbVq9eLYvFor59+xZugQUkL30uX75cFovFbnJzcyvCau9MXr+nly5d0tixYxUQECCr1aratWuXiH9/89JnWFjYTd9Ti8WiXr16FWHF+ZfX7+miRYtUp04dubu7KzAwUBMnTtQff/xRRNX+PwaQC6tXrzZcXV2NZcuWGYcPHzYef/xxw9fX1/jpp59uuf3OnTsNZ2dn48UXXzSOHDlizJgxwyhTpoxx8ODBIq48b/La5549e4wpU6YYH374oeHv728sXLiwaAu+A3nt9ZFHHjHefPNN48CBA0ZiYqIRHh5u+Pj4GKdPny7iyvMmr31u377diI6ONo4cOWKcOHHCWLRokeHs7Gxs3ry5iCvPu7z2ekNycrJRpUoVo127dkafPn2Kptg7kNc+o6KiDG9vb+PMmTO26ezZs0Vcdf7ktdfMzEyjefPmRs+ePY0dO3YYycnJRmxsrBEfH1/EledNXvu8cOGC3ffz0KFDhrOzsxEVFVW0hedDXntduXKlYbVajZUrVxrJycnGli1bjICAAGPixIlFWjeBEbnSsmVLY+zYsbb5rKwso3LlykZkZOQttx8wYIDRq1cvu2WtWrUyxowZU6h13qm89vln1apVK1GB8U56NQzDuHbtmuHl5WW8//77hVVigbjTPg3DMJo1a2bMmDGjMMorUPnp9dq1a0br1q2NpUuXGo8++miJCIx57TMqKsrw8fEpouoKVl57ffvtt40aNWoYV65cKaoSC8Sd/j1duHCh4eXlZWRkZBRWiQUmr72OHTvW6NSpk92ySZMmGW3atCnUOv+KW9K4rStXrmj//v3q0qWLbZmTk5O6dOmi3bt333Kf3bt3220vSd26dctx++IgP32WVAXR6++//66rV6+qfPnyhVXmHbvTPg3DUExMjI4dO6b27dsXZql3LL+9Pvvss7rnnnv02GOPFUWZdyy/fWZkZKhatWoKDAxUnz59dPjw4aIo947kp9f169crNDRUY8eOlZ+fnxo2bKh58+YpKyurqMrOs4L49+i9997ToEGD5OHhUVhlFoj89Nq6dWvt37/fdtv6+++/18aNG9WzZ88iqfkGlyI9G0qk8+fPKysrS35+fnbL/fz8dPTo0Vvuc/bs2Vtuf/bs2UKr807lp8+SqiB6nTp1qipXrnzTfwyKk/z2mZaWpipVqigzM1POzs5666231LVr18Iu947kp9cdO3bovffeU3x8fBFUWDDy02edOnW0bNkyNW7cWGlpaVqwYIFat26tw4cP69577y2KsvMlP71+//33+u9//6shQ4Zo48aNOnHihJ544gldvXpVs2bNKoqy8+xO/z3as2ePDh06pPfee6+wSiww+en1kUce0fnz59W2bVsZhqFr167pH//4h5555pmiKNmGwAggz+bPn6/Vq1crNja2RL08kFteXl6Kj49XRkaGYmJiNGnSJNWoUUNhYWGOLq3A/Prrrxo2bJiWLFmiihUrOrqcQhUaGqrQ0FDbfOvWrVWvXj0tXrxYc+fOdWBlBS87O1v33HOP3n33XTk7O+u+++7TDz/8oJdeeqnYBsY79d5776lRo0Zq2bKlo0spFLGxsZo3b57eeusttWrVSidOnND48eM1d+5czZw5s8jqIDDitipWrChnZ2f99NNPdst/+ukn+fv733Iff3//PG1fHOSnz5LqTnpdsGCB5s+fr23btqlx48aFWeYdy2+fTk5OqlWrliSpadOmSkxMVGRkZLEOjHntNSkpSSkpKerdu7dtWXZ2tiTJxcVFx44dU82aNQu36HwoiL+nZcqUUbNmzXTixInCKLHA5KfXgIAAlSlTRs7OzrZl9erV09mzZ3XlyhW5uroWas35cSff099++02rV6/Ws88+W5glFpj89Dpz5kwNGzZMo0aNkiQ1atRIv/32m0aPHq3p06fLyaloni7kGUbclqurq+677z7FxMTYlmVnZysmJsbuf+1/Fhoaare9JH3xxRc5bl8c5KfPkiq/vb744ouaO3euNm/erObNmxdFqXekoL6n2dnZyszMLIwSC0xee61bt64OHjyo+Ph42/TAAw+oY8eOio+PV2BgYFGWn2sF8T3NysrSwYMHFRAQUFhlFoj89NqmTRudOHHCFv4l6X//+58CAgKKZViU7ux7umbNGmVmZmro0KGFXWaByE+vv//++02h8MZ/CAzDKLxi/6pIX7FBibV69WrDarUay5cvN44cOWKMHj3a8PX1tX00xbBhw4xp06bZtt+5c6fh4uJiLFiwwEhMTDRmzZpVYj5WJy99ZmZmGgcOHDAOHDhgBAQEGFOmTDEOHDhgHD9+3FEt5Fpee50/f77h6upqrF271u7jLH799VdHtZAree1z3rx5xtatW42kpCTjyJEjxoIFCwwXFxdjyZIljmoh1/La61+VlLek89rnnDlzjC1bthhJSUnG/v37jUGDBhlubm7G4cOHHdVCruW119TUVMPLy8sYN26ccezYMWPDhg3GPffcYzz33HOOaiFX8vtnt23btsbAgQOLutw7ktdeZ82aZXh5eRkffvih8f333xtbt241atasaQwYMKBI6yYwItdef/11o2rVqoarq6vRsmVL4+uvv7at69Chg/Hoo4/abf/xxx8btWvXNlxdXY0GDRoYn3/+eRFXnD956TM5OdmQdNPUoUOHoi88H/LSa7Vq1W7Z66xZs4q+8DzKS5/Tp083atWqZbi5uRnlypUzQkNDjdWrVzug6vzJ69/TPyspgdEw8tbnhAkTbNv6+fkZPXv2NL799lsHVJ0/ef2e7tq1y2jVqpVhtVqNGjVqGM8//7xx7dq1Iq467/La59GjRw1JxtatW4u40juXl16vXr1qzJ4926hZs6bh5uZmBAYGGk888YTxyy+/FGnNFsMoyvFMAAAAlDQ8wwgAAABTBEYAAACYIjACAADAFIERAAAApgiMAAAAMEVgBAAAgCkCIwAAAEwRGAEAAGCKwAgAAABTBEYAAACYIjACAADAFIERAAAApv4/g3M08iLW11kAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#Usando moddelo de regressão pra verificar como que cada variável vai impactar o modelo \n", "\n", "from sklearn.feature_selection import mutual_info_regression \n", "import matplotlib.pyplot as plt\n", "\n", "X, y = car_train.drop(['Price', 'Name'], axis=1), car_train['Price'] #Escolhendo todas variáveis menos o preço e o nome e escolhendo o preço como objetivo \n", "\n", "importances = mutual_info_regression(X, y) # Calculando a importância de cada característica com a variável Preço \n", "feat_importances = pd.Series(importances, car_train.columns[1:len(car_train.columns)-1]) #Criando uma série para armazenar as pontuações calculadas\n", "feat_importances.plot(kind='barh') # Vizualização das características através de um gráfico \n", "\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "id": "ibOYVh-WxyP7", "outputId": "bacb450e-4331-450b-fedb-b7a6aab71b25" }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAApQAAAGdCAYAAACsKONpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAABC7klEQVR4nO3deVyU9f7//+cgMiCrW4CGgor7SpoHTUXFA2qmVm5ZhuZySjuupaamZgmW7XVa7ATZySyNzI+5JUco0XJJyQU9SiBaGqUJUoYK1/cPf86vyRWvgRF43G+36xbX8n5fr+vdNDx7X3MNFsMwDAEAAAA3yMXZBQAAAKBsI1ACAADAFAIlAAAATCFQAgAAwBQCJQAAAEwhUAIAAMAUAiUAAABMIVACAADAFFdnF4DyoaioSD/++KO8vb1lsVicXQ4AALgOhmHo9OnTqlWrllxcbnyekUAJh/jxxx8VFBTk7DIAAMANOHLkiG699dYbbk+ghEN4e3tLuvCC9PHxcXI1AADgeuTl5SkoKMj2e/xGESjhEBdvc/v4+BAoAQAoY8x+XI2HcgAAAGAKgRIAAACmECgBAABgCoESAAAAphAoAQAAYAqBEgAAAKbwtUFwqOaz18nFWsXZZZSKrLjezi4BAICbAjOUAAAAMIVACQAAAFMIlAAAADCFQAkAAABTCJQ3mZ9//lkPP/yw6tSpI6vVqoCAAEVFRSk1NdVh5wgODtZLL73ksP4AAEDFxlPeN5l77rlHZ8+e1Xvvvad69erpp59+UlJSkk6cOOHs0gAAAC6LGcqbyKlTp/TVV19pwYIF6tq1q+rWravbb79d06dP11133WU7ZuTIkapZs6Z8fHzUrVs3paWl2frIyMhQ37595e/vLy8vL7Vr104bNmyw7Y+IiNDhw4c1ceJEWSwWWSwWSdLhw4fVp08fVa1aVZ6enmrWrJlWr15dugMAAADKJALlTcTLy0teXl5asWKFCgoKLnvMgAEDlJOTozVr1mjHjh0KCwtT9+7ddfLkSUlSfn6+evXqpaSkJO3cuVPR0dHq06ePsrOzJUmJiYm69dZb9dRTT+nYsWM6duyYJGns2LEqKCjQl19+qd27d2vBggXy8vK6Yq0FBQXKy8uzWwAAQMVEoLyJuLq6KiEhQe+99578/PzUsWNHPfHEE/ruu+8kSZs2bdLWrVu1bNkytW3bVqGhoVq4cKH8/Py0fPlySVKrVq00ZswYNW/eXKGhoZo3b57q16+vlStXSpKqVaumSpUqydvbWwEBAQoICJAkZWdnq2PHjmrRooXq1aunO++8U507d75irbGxsfL19bUtQUFBJTw6AADgZkWgvMncc889+vHHH7Vy5UpFR0crOTlZYWFhSkhIUFpamvLz81W9enXbbKaXl5cyMzOVkZEh6cIM5ZQpU9SkSRP5+fnJy8tL6enpthnKK/nnP/+pp59+Wh07dtTs2bNtIfZKpk+frtzcXNty5MgRh40BAAAoW3go5ybk7u6uHj16qEePHpo1a5ZGjhyp2bNn65FHHlFgYKCSk5MvaePn5ydJmjJlir744gstXLhQDRo0kIeHh+69916dPXv2quccOXKkoqKi9Pnnn2v9+vWKjY3V888/r0cfffSyx1utVlmtVrOXCgAAygFmKMuApk2b6rffflNYWJiOHz8uV1dXNWjQwG6pUaOGJCk1NVUxMTHq37+/WrRooYCAAGVlZdn15+bmpsLCwkvOExQUpH/84x9KTEzU5MmTtWjRotK4PAAAUMYRKG8iJ06cULdu3fSf//xH3333nTIzM7Vs2TI9++yz6tu3ryIjIxUeHq5+/fpp/fr1ysrK0ubNmzVjxgxt375dkhQaGqrExETt2rVLaWlpuu+++1RUVGR3nuDgYH355Zf64Ycf9Msvv0iSJkyYoHXr1ikzM1PffvutNm7cqCZNmpT6GAAAgLKHW943ES8vL7Vv314vvviiMjIydO7cOQUFBWnUqFF64oknZLFYtHr1as2YMUPDhw/Xzz//rICAAHXu3Fn+/v6SpBdeeEEjRoxQhw4dVKNGDU2dOvWSJ7CfeuopjRkzRvXr11dBQYEMw1BhYaHGjh2ro0ePysfHR9HR0XrxxRedMQwAAKCMsRiGYTi7CJR9eXl5F572nvCxXKxVnF1OqciK6+3sEgAAMOXi7+/c3Fz5+PjccD/c8gYAAIApBEoAAACYwmco4VB75kaZmjIHAABlDzOUAAAAMIVACQAAAFMIlAAAADCFQAkAAABTCJQAAAAwhUAJAAAAUwiUAAAAMIVACQAAAFMIlAAAADCFQAkAAABTCJQAAAAwhUAJAAAAUwiUAAAAMIVACQAAAFMIlAAAADCFQAkAAABTCJQAAAAwhUAJAAAAU1ydXQDKl+az18nFWsXZZQAAypGsuN7OLgHXwAwlAAAATCFQAgAAwBQCJQAAAEwhUAIAAMAUAqWTxcTEyGKxyGKxyM3NTQ0aNNBTTz2l8+fPO7s0AACA68JT3jeB6OhoxcfHq6CgQKtXr9bYsWNVuXJlTZ8+3al1nT17Vm5ubk6tAQAA3PyYobwJWK1WBQQEqG7dunr44YcVGRmplStX6tdff9WwYcNUtWpVValSRT179tTBgwclSYZhqGbNmlq+fLmtn9atWyswMNC2vmnTJlmtVv3++++SpFOnTmnkyJGqWbOmfHx81K1bN6WlpdmOnzNnjlq3bq133nlHISEhcnd3L6URAAAAZRmB8ibk4eGhs2fPKiYmRtu3b9fKlSu1ZcsWGYahXr166dy5c7JYLOrcubOSk5MlSb/++qvS09N15swZ7d+/X5KUkpKidu3aqUqVC98LOWDAAOXk5GjNmjXasWOHwsLC1L17d508edJ27kOHDumTTz5RYmKidu3adcUaCwoKlJeXZ7cAAICKiUB5EzEMQxs2bNC6detUp04drVy5Uu+88446deqkVq1a6YMPPtAPP/ygFStWSJIiIiJsgfLLL79UmzZt7LYlJyerS5cuki7MVm7dulXLli1T27ZtFRoaqoULF8rPz89ulvPs2bNavHix2rRpo5YtW16x1tjYWPn6+tqWoKCgEhkTAABw8yNQ3gRWrVolLy8vubu7q2fPnho0aJBiYmLk6uqq9u3b246rXr26GjVqpPT0dElSly5dtG/fPv38889KSUlRRESELVCeO3dOmzdvVkREhCQpLS1N+fn5ql69ury8vGxLZmamMjIybOeoW7euatasec2ap0+frtzcXNty5MgRxw4KAAAoM3go5ybQtWtXvfHGG3Jzc1OtWrXk6uqqlStXXrNdixYtVK1aNaWkpCglJUXPPPOMAgICtGDBAm3btk3nzp1Thw4dJEn5+fkKDAy0zV7+mZ+fn+1nT0/P66rZarXKarVe17EAAKB8I1DeBDw9PdWgQQO7bU2aNNH58+f1zTff2ELhiRMndODAATVt2lSSZLFY1KlTJ3322Wfau3ev7rjjDlWpUkUFBQV666231LZtW1tADAsL0/Hjx+Xq6qrg4OBSvT4AAFC+ccv7JhUaGqq+fftq1KhR2rRpk9LS0nT//ferdu3a6tu3r+24iIgIffjhh2rdurW8vLzk4uKizp0764MPPrB9flKSIiMjFR4ern79+mn9+vXKysrS5s2bNWPGDG3fvt0ZlwgAAMoJAuVNLD4+XrfddpvuvPNOhYeHyzAMrV69WpUrV7Yd06VLFxUWFto+KyldCJl/3WaxWLR69Wp17txZw4cPV8OGDTV48GAdPnxY/v7+pXhVAACgvLEYhmE4uwiUfXl5eRee9p7wsVysVZxdDgCgHMmK6+3sEsqti7+/c3Nz5ePjc8P9MEMJAAAAUwiUAAAAMIWnvOFQe+ZGmZoyBwAAZQ8zlAAAADCFQAkAAABTCJQAAAAwhUAJAAAAUwiUAAAAMIVACQAAAFMIlAAAADCFQAkAAABTCJQAAAAwhUAJAAAAUwiUAAAAMIVACQAAAFMIlAAAADCFQAkAAABTCJQAAAAwhUAJAAAAUwiUAAAAMIVACQAAAFNcnV0Aypfms9fJxVrF2WUADpUV19vZJQDATY0ZSgAAAJhCoAQAAIApBEoAAACYQqAsZxISEuTn5+fsMgAAQAVCoCxFMTExslgslyzR0dEOO8egQYP0v//9z2H9AQAAXAtPeZey6OhoxcfH222zWq0O69/Dw0MeHh4O6w8AAOBamKEsZVarVQEBAXZL1apVJUkWi0XvvPOO+vfvrypVqig0NFQrV660a79y5UqFhobK3d1dXbt21XvvvSeLxaJTp05JuvSW95w5c9S6dWu9//77Cg4Olq+vrwYPHqzTp0/bjikqKlJsbKxCQkLk4eGhVq1aafny5SU+FgAAoHwgUN5k5s6dq4EDB+q7775Tr169NHToUJ08eVKSlJmZqXvvvVf9+vVTWlqaxowZoxkzZlyzz4yMDK1YsUKrVq3SqlWrlJKSori4ONv+2NhYLV68WG+++ab27t2riRMn6v7771dKSsoV+ywoKFBeXp7dAgAAKiYCZSlbtWqVvLy87Jb58+fb9sfExGjIkCFq0KCB5s+fr/z8fG3dulWS9NZbb6lRo0Z67rnn1KhRIw0ePFgxMTHXPGdRUZESEhLUvHlzderUSQ888ICSkpIkXQiG8+fP17vvvquoqCjVq1dPMTExuv/++/XWW29dsc/Y2Fj5+vralqCgIHMDAwAAyiw+Q1nKunbtqjfeeMNuW7Vq1Ww/t2zZ0vazp6enfHx8lJOTI0k6cOCA2rVrZ9f29ttvv+Y5g4OD5e3tbVsPDAy09Xno0CH9/vvv6tGjh12bs2fPqk2bNlfsc/r06Zo0aZJtPS8vj1AJAEAFRaAsZZ6enmrQoMEV91euXNlu3WKxqKioyNQ5r9Znfn6+JOnzzz9X7dq17Y672sNCVqvVoQ8TAQCAsotAWYY0atRIq1evttu2bds2U302bdpUVqtV2dnZ6tKli6m+AABAxUSgLGUFBQU6fvy43TZXV1fVqFHjmm3HjBmjF154QVOnTtVDDz2kXbt2KSEhQdKFWccb4e3trSlTpmjixIkqKirSHXfcodzcXKWmpsrHx0cPPvjgDfULAAAqDgJlKVu7dq0CAwPttjVq1Ej79++/ZtuQkBAtX75ckydP1ssvv6zw8HDNmDFDDz/8sKnbz/PmzVPNmjUVGxur77//Xn5+fgoLC9MTTzxxw30CAICKw2IYhuHsInDjnnnmGb355ps6cuSIU+vIy8u78LT3hI/lYq3i1FoAR8uK6+3sEgCgRFz8/Z2bmysfH58b7ocZyjLmX//6l9q1a6fq1asrNTVVzz33nMaNG+fssgAAQAVGoCxjDh48qKefflonT55UnTp1NHnyZE2fPt3ZZQEAgAqMW95wCEdNmQMAgNLjqN/f/KUcAAAAmEKgBAAAgCkESgAAAJhCoAQAAIApBEoAAACYQqAEAACAKQRKAAAAmEKgBAAAgCkESgAAAJhCoAQAAIApBEoAAACYQqAEAACAKQRKAAAAmEKgBAAAgCkESgAAAJhCoAQAAIApBEoAAACYQqAEAACAKa7OLgDlS/PZ6+RireLsMoolK663s0sAAKBMY4YSAAAAphAoAQAAYAqBEgAAAKYQKJ0oIiJCEyZMsK0HBwfrpZdeclo9AAAAN4JA6WAxMTGyWCz6xz/+ccm+sWPHymKxKCYmRpKUmJioefPmlXKFAAAAjkWgLAFBQUFaunSpzpw5Y9v2xx9/aMmSJapTp45tW7Vq1eTt7e2MEgEAAByGQFkCwsLCFBQUpMTERNu2xMRE1alTR23atLFt++st7786deqURo4cqZo1a8rHx0fdunVTWlqabX9GRob69u0rf39/eXl5qV27dtqwYYNdH8eOHVPv3r3l4eGhkJAQLVmy5JJb69c6DwAAwNUQKEvIiBEjFB8fb1t/9913NXz48GL1MWDAAOXk5GjNmjXasWOHwsLC1L17d508eVKSlJ+fr169eikpKUk7d+5UdHS0+vTpo+zsbFsfw4YN048//qjk5GR98sknevvtt5WTk1Os81xOQUGB8vLy7BYAAFAxEShLyP33369Nmzbp8OHDOnz4sFJTU3X//fdfd/tNmzZp69atWrZsmdq2bavQ0FAtXLhQfn5+Wr58uSSpVatWGjNmjJo3b67Q0FDNmzdP9evX18qVKyVJ+/fv14YNG7Ro0SK1b99eYWFheuedd+xuxV/PeS4nNjZWvr6+tiUoKOgGRwoAAJR1/KWcElKzZk317t1bCQkJMgxDvXv3Vo0aNa67fVpamvLz81W9enW77WfOnFFGRoakCzOUc+bM0eeff65jx47p/PnzOnPmjG2G8sCBA3J1dVVYWJitfYMGDVS1atVinedypk+frkmTJtnW8/LyCJUAAFRQBMoSNGLECI0bN06S9PrrrxerbX5+vgIDA5WcnHzJPj8/P0nSlClT9MUXX2jhwoVq0KCBPDw8dO+99+rs2bMOPc/lWK1WWa3W6z4PAAAovwiUJSg6Olpnz56VxWJRVFRUsdqGhYXp+PHjcnV1VXBw8GWPSU1NVUxMjPr37y/pQjjMysqy7W/UqJHOnz+vnTt36rbbbpMkHTp0SL/++muxzgMAAHA1fIayBFWqVEnp6enat2+fKlWqVKy2kZGRCg8PV79+/bR+/XplZWVp8+bNmjFjhrZv3y5JCg0NVWJionbt2qW0tDTdd999KioqsvXRuHFjRUZGavTo0dq6dat27typ0aNHy8PDQxaL5brPAwAAcDUEyhLm4+MjHx+fYrezWCxavXq1OnfurOHDh6thw4YaPHiwDh8+LH9/f0nSCy+8oKpVq6pDhw7q06ePoqKi7D4vKUmLFy+Wv7+/OnfurP79+2vUqFHy9vaWu7v7dZ8HAADgaiyGYRjOLgKl5+jRowoKCtKGDRvUvXt3h/Wbl5d34WnvCR/LxVrFYf2Whqy43s4uAQAAp7j4+zs3N/eGJsAu4jOU5dx///tf5efnq0WLFjp27Jgef/xxBQcHq3Pnzs4uDQAAlBMEynLu3LlzeuKJJ/T999/L29tbHTp00AcffKDKlSs7uzQAAFBOcMsbDuGoKXMAAFB6HPX7m4dyAAAAYAqBEgAAAKYQKAEAAGAKgRIAAACmECgBAABgCoESAAAAphAoAQAAYAqBEgAAAKYQKAEAAGAKgRIAAACmECgBAABgCoESAAAAphAoAQAAYAqBEgAAAKYQKAEAAGAKgRIAAACmECgBAABgCoESAAAAprg6uwCUL81nr5OLtcpVj8mK611K1QAAgNLADCUAAABMIVACAADAFAIlAAAATCFQAgAAwJRyHyiPHDmiESNGqFatWnJzc1PdunU1fvx4nThxwtmlXbeIiAhZLJYrLhEREc4uEQAAVGDl+inv77//XuHh4WrYsKE+/PBDhYSEaO/evXrssce0Zs0aff3116pWrZqzy5RhGCosLJSr6+X/dSQmJurs2bOSLgTk22+/XRs2bFCzZs0kSW5ubqVWKwAAwF+V6xnKsWPHys3NTevXr1eXLl1Up04d9ezZUxs2bNAPP/ygGTNm6LXXXlPz5s1tbVasWCGLxaI333zTti0yMlIzZ86UJM2ZM0etW7fW+++/r+DgYPn6+mrw4ME6ffq07fiioiLFxsYqJCREHh4eatWqlZYvX27bn5ycLIvFojVr1ui2226T1WrVpk2brngd1apVU0BAgAICAlSzZk1JUvXq1RUQEKD77rtPTz75pN3xP//8s9zc3JSUlCRJCg4O1rx58zRkyBB5enqqdu3aev311+3anDp1SiNHjlTNmjXl4+Ojbt26KS0trbhDDgAAKqByGyhPnjypdevW6ZFHHpGHh4fdvoCAAA0dOlQfffSRunTpon379unnn3+WJKWkpKhGjRpKTk6WJJ07d05btmyxu62ckZGhFStWaNWqVVq1apVSUlIUFxdn2x8bG6vFixfrzTff1N69ezVx4kTdf//9SklJsatj2rRpiouLU3p6ulq2bHlD1zly5EgtWbJEBQUFtm3/+c9/VLt2bXXr1s227bnnnlOrVq20c+dOTZs2TePHj9cXX3xh2z9gwADl5ORozZo12rFjh8LCwtS9e3edPHnysuctKChQXl6e3QIAACqmchsoDx48KMMw1KRJk8vub9KkiX799Vfdcsstqlatmi3sJScna/Lkybb1rVu36ty5c+rQoYOtbVFRkRISEtS8eXN16tRJDzzwgG02sKCgQPPnz9e7776rqKgo1atXTzExMbr//vv11ltv2dXw1FNPqUePHqpfv/4N33q/++67JUmfffaZbVtCQoJiYmJksVhs2zp27Khp06apYcOGevTRR3XvvffqxRdflCRt2rRJW7du1bJly9S2bVuFhoZq4cKF8vPzs5tZ/bPY2Fj5+vralqCgoBuqHwAAlH3lNlBeZBjGVfdbLBZ17txZycnJOnXqlPbt26dHHnlEBQUF2r9/v1JSUtSuXTtVqfL///WX4OBgeXt729YDAwOVk5MjSTp06JB+//139ejRQ15eXrZl8eLFysjIsDt327ZtTV+fu7u7HnjgAb377ruSpG+//VZ79uxRTEyM3XHh4eGXrKenp0uS0tLSlJ+fr+rVq9vVnJmZeUnNF02fPl25ubm25ciRI6avBQAAlE3l9qGcBg0ayGKxKD09Xf37979kf3p6uqpWraqaNWsqIiJCb7/9tr766iu1adNGPj4+tpCZkpKiLl262LWtXLmy3brFYlFRUZEkKT8/X5L0+eefq3bt2nbHWa1Wu3VPT0/T1ylduO3dunVrHT16VPHx8erWrZvq1q173e3z8/MVGBhou83/Z35+fpdtY7VaL7keAABQMZXbGcrq1aurR48e+te//qUzZ87Y7Tt+/Lg++OADDRo0SBaLxfY5ymXLltk+KxkREaENGzYoNTW1WF/L07RpU1mtVmVnZ6tBgwZ2S0ndFm7RooXatm2rRYsWacmSJRoxYsQlx3z99deXrF/8OEBYWJiOHz8uV1fXS2quUaNGidQMAADKj3IbKCXptddeU0FBgaKiovTll1/qyJEjWrt2rXr06KHatWvrmWeekSS1bNlSVatW1ZIlS+wC5YoVK1RQUKCOHTte9zm9vb01ZcoUTZw4Ue+9954yMjL07bff6tVXX9V7771XEpcp6cIsZVxcnAzDuOyMbGpqqp599ln973//0+uvv65ly5Zp/Pjxki48xR4eHq5+/fpp/fr1ysrK0ubNmzVjxgxt3769xGoGAADlQ7kOlKGhodq+fbvq1aungQMHqn79+ho9erS6du2qLVu22B6EsVgs6tSpkywWi+644w5JF0Kmj4+P2rZtW+xb0/PmzdOsWbMUGxurJk2aKDo6Wp9//rlCQkIcfo0XDRkyRK6urhoyZIjc3d0v2T958mRt375dbdq00dNPP60XXnhBUVFRki5c/+rVq9W5c2cNHz5cDRs21ODBg3X48GH5+/uXWM0AAKB8sBjXemoFZUJWVpbq16+vbdu2KSwszG5fcHCwJkyYoAkTJpTY+fPy8i487T3hY7lYq1z12Ky43iVWBwAAuH4Xf3/n5ubKx8fnhvsptw/lVBTnzp3TiRMnNHPmTP3tb3+7JEwCAACUtHJ9y7ssadasmd1X9vx5+eCDD67YLjU1VYGBgdq2bZvdX/cBAAAoLdzyvkkcPnxY586du+w+f39/u++9vBk5asocAACUHm55lzPF+d5IAACAmwm3vAEAAGAKgRIAAACmECgBAABgCoESAAAAphAoAQAAYAqBEgAAAKYQKAEAAGAKgRIAAACmECgBAABgCoESAAAAphAoAQAAYAqBEgAAAKYQKAEAAGAKgRIAAACmECgBAABgCoESAAAAphAoAQAAYIqrswtA+dJ89jq5WKs4uwwAAMqNrLjezi7hmpihBAAAgCkESgAAAJhCoAQAAIApBMqbyJw5c9S6dWvT/SQkJMjPz890PwAAANejzAdKi8Vy1WXOnDnOLvG6TZkyRUlJSab7GTRokP73v/85oCIAAIBrK/NPeR87dsz280cffaQnn3xSBw4csG3z8vKy/WwYhgoLC+XqenNetpeXl129N8rDw0MeHh4OqAgAAODayvwMZUBAgG3x9fWVxWKxre/fv1/e3t5as2aNbrvtNlmtVm3atEkZGRnq27ev/P395eXlpXbt2mnDhg12/QYHB2v+/PkaMWKEvL29VadOHb399tu2/WfPntW4ceMUGBgod3d31a1bV7Gxsbb9FotFb731lu68805VqVJFTZo00ZYtW3To0CFFRETI09NTHTp0UEZGhq3NX295Jycn6/bbb5enp6f8/PzUsWNHHT58WJKUlpamrl27ytvbWz4+Prrtttu0fft2SZe/5f3GG2+ofv36cnNzU6NGjfT+++/b7bdYLHrnnXfUv39/ValSRaGhoVq5cqWpfzcAAKBiKPOB8npMmzZNcXFxSk9PV8uWLZWfn69evXopKSlJO3fuVHR0tPr06aPs7Gy7ds8//7zatm2rnTt36pFHHtHDDz9sm/185ZVXtHLlSn388cc6cOCAPvjgAwUHB9u1nzdvnoYNG6Zdu3apcePGuu+++zRmzBhNnz5d27dvl2EYGjdu3GVrPn/+vPr166cuXbrou+++05YtWzR69GhZLBZJ0tChQ3Xrrbdq27Zt2rFjh6ZNm6bKlStftq9PP/1U48eP1+TJk7Vnzx6NGTNGw4cP18aNG+2Omzt3rgYOHKjvvvtOvXr10tChQ3Xy5MnL9llQUKC8vDy7BQAAVEw3571fB3vqqafUo0cP23q1atXUqlUr2/q8efP06aefauXKlXYBr1evXnrkkUckSVOnTtWLL76ojRs3qlGjRsrOzlZoaKjuuOMOWSwW1a1b95LzDh8+XAMHDrS1Dw8P16xZsxQVFSVJGj9+vIYPH37ZmvPy8pSbm6s777xT9evXlyQ1adLEtj87O1uPPfaYGjduLEkKDQ294vUvXLhQMTExtmuZNGmSvv76ay1cuFBdu3a1HRcTE6MhQ4ZIkubPn69XXnlFW7duVXR09CV9xsbGau7cuVc8JwAAqDgqxAxl27Zt7dbz8/M1ZcoUNWnSRH5+fvLy8lJ6evolM5QtW7a0/XzxVnpOTo6kC+Fr165datSokf75z39q/fr1l5z3z+39/f0lSS1atLDb9scff1x2dq9atWqKiYlRVFSU+vTpo5dfftnu86KTJk3SyJEjFRkZqbi4OLtb53+Vnp6ujh072m3r2LGj0tPTr1ivp6enfHx8bNf7V9OnT1dubq5tOXLkyBXPDwAAyrcKESg9PT3t1qdMmaJPP/1U8+fP11dffaVdu3apRYsWOnv2rN1xf72FbLFYVFRUJEkKCwtTZmam5s2bpzNnzmjgwIG69957r9j+4q3qy2272OdfxcfHa8uWLerQoYM++ugjNWzYUF9//bWkC5+33Lt3r3r37q3//ve/atq0qT799NPrHpPLudr1/pXVapWPj4/dAgAAKqYKESj/KjU1VTExMerfv79atGihgIAAZWVlFbsfHx8fDRo0SIsWLdJHH32kTz755IqfObxRbdq00fTp07V582Y1b95cS5Ysse1r2LChJk6cqPXr1+vuu+9WfHz8Zfto0qSJUlNT7balpqaqadOmDq0VAABUTBXiM5R/FRoaqsTERPXp00cWi0WzZs264kzclbzwwgsKDAxUmzZt5OLiomXLlikgIMBhXyiemZmpt99+W3fddZdq1aqlAwcO6ODBgxo2bJjOnDmjxx57TPfee69CQkJ09OhRbdu2Tffcc89l+3rsscc0cOBAtWnTRpGRkfq///s/JSYmXvJkOwAAwI2okIHyhRde0IgRI9ShQwfVqFFDU6dOLfZTyt7e3nr22Wd18OBBVapUSe3atdPq1avl4uKYSd8qVapo//79eu+993TixAkFBgZq7NixGjNmjM6fP68TJ05o2LBh+umnn1SjRg3dfffdV3xIpl+/fnr55Ze1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DM2ZM0cWi0UWi0Wurq6qUaOGOnfurJdeekkFBQXXbB8UFKRjx46pefPmpVAtAADA9TE1Q/nOO+9o6NCheuONNzR58mRVq1ZN3t7ejqrtpnP27FnTfTRr1kzHjh1Tdna2Nm7cqAEDBig2NlYdOnTQ6dOnr3ruSpUqKSAgQK6uPJwPAABuHjccKJ999lk9+uijWrp0qYYPHy7p0lvef5Wdna2+ffvKy8tLPj4+GjhwoH766Sfb/oszie+++67q1KkjLy8vPfLIIyosLNSzzz6rgIAA3XLLLXrmmWfs+j116pRGjhypmjVrysfHR926dVNaWpokKSEhQXPnzlVaWpptdjAhIeGa7f5czzvvvKOQkBC5u7tLujAr26JFC3l4eKh69eqKjIzUb7/9dl3j5urqqoCAANWqVUstWrTQo48+qpSUFO3Zs0cLFiywHRccHKx58+Zp2LBh8vHx0ejRo+1ueRcVFenWW2/VG2+8Ydf/zp075eLiosOHDxfrGt9//30FBwfL19dXgwcPvmq4BQAA+LMbCpRTp07VvHnztGrVKvXv3/+62hQVFalv3746efKkUlJS9MUXX+j777/XoEGD7I7LyMjQmjVrtHbtWn344Yf697//rd69e+vo0aNKSUnRggULNHPmTH3zzTe2NgMGDFBOTo7WrFmjHTt2KCwsTN27d9fJkyc1aNAgTZ482TYzeOzYMds5r9buokOHDumTTz5RYmKidu3apWPHjmnIkCEaMWKE0tPTlZycrLvvvluGYdzIUEqSGjdurJ49eyoxMdFu+8KFC9WqVSvt3LlTs2bNstvn4uKiIUOGaMmSJXbbP/jgA3Xs2FF169a97mvMyMjQihUrtGrVKq1atUopKSmKi4u7as0FBQXKy8uzWwAAQMVU7Huna9as0WeffaakpCR169btutslJSVp9+7dyszMVFBQkCRp8eLFatasmbZt26Z27dpJuhA83333XXl7e6tp06bq2rWrDhw4oNWrV8vFxUWNGjXSggULtHHjRrVv316bNm3S1q1blZOTI6vVKulCEFuxYoWWL1+u0aNHy8vLyzYzeNH1tJMu3GpevHixatasKUn69ttvdf78ed1999220NaiRYviDuMlGjdurPXr19tt69atmyZPnmxbz8rKsts/dOhQPf/888rOzladOnVUVFSkpUuXaubMmcW6xqKiIiUk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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#Usando outro modelo de regressão \n", "\n", "from sklearn.ensemble import ExtraTreesRegressor\n", "\n", "tree = ExtraTreesRegressor(n_estimators=50)\n", "tree = tree.fit(X, y)\n", "\n", "feat_importances = pd.Series(tree.feature_importances_, car_train.columns[1:len(car_train.columns)-1])\n", "feat_importances.plot(kind='barh')\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "BAeDUR4hxyP8" }, "source": [ "### Normalização dos dados" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "id": "H7Dz5qTwxyP9", "outputId": "75f7b1cc-eb47-4037-d4c3-fcd78e78c5ad" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameLocationYearKilometers_DrivenFuel_TypeTransmissionOwner_TypeMileageEnginePowerSeatsPrice
0Maruti Wagon R LXI CNG920100.0110510110.7930830.0695940.0455695.01.75
1Hyundai Creta 1.6 CRDi SX Option1020150.0062821110.5864640.1782660.1749715.012.50
2Honda Jazz V220110.0070513110.5426360.1069970.1036525.04.50
3Maruti Ertiga VDI220120.0133591110.6192610.1161150.1037667.06.00
4Audi A4 New 2.0 TDI Multitronic320130.0062311020.4531900.2500930.2027395.017.74
.......................................
6014Maruti Swift VDI420140.0041841110.8467500.1161150.0756945.04.75
6015Hyundai Xcent 1.1 CRDi S620150.0153591110.7274900.0922960.0699895.04.00
6016Mahindra Xylo D4 BSIV620120.0084351120.4174120.3487160.1479658.02.90
6017Maruti Wagon R VXI820130.0070513110.5635060.0695940.0625715.02.65
6018Chevrolet Beat Diesel520110.0072051110.7584970.0580570.0445045.02.50
\n", "

5872 rows × 12 columns

\n", "
" ], "text/plain": [ " Name Location Year Kilometers_Driven \\\n", "0 Maruti Wagon R LXI CNG 9 2010 0.011051 \n", "1 Hyundai Creta 1.6 CRDi SX Option 10 2015 0.006282 \n", "2 Honda Jazz V 2 2011 0.007051 \n", "3 Maruti Ertiga VDI 2 2012 0.013359 \n", "4 Audi A4 New 2.0 TDI Multitronic 3 2013 0.006231 \n", "... ... ... ... ... \n", "6014 Maruti Swift VDI 4 2014 0.004184 \n", "6015 Hyundai Xcent 1.1 CRDi S 6 2015 0.015359 \n", "6016 Mahindra Xylo D4 BSIV 6 2012 0.008435 \n", "6017 Maruti Wagon R VXI 8 2013 0.007051 \n", "6018 Chevrolet Beat Diesel 5 2011 0.007205 \n", "\n", " Fuel_Type Transmission Owner_Type Mileage Engine Power \\\n", "0 0 1 1 0.793083 0.069594 0.045569 \n", "1 1 1 1 0.586464 0.178266 0.174971 \n", "2 3 1 1 0.542636 0.106997 0.103652 \n", "3 1 1 1 0.619261 0.116115 0.103766 \n", "4 1 0 2 0.453190 0.250093 0.202739 \n", "... ... ... ... ... ... ... \n", "6014 1 1 1 0.846750 0.116115 0.075694 \n", "6015 1 1 1 0.727490 0.092296 0.069989 \n", "6016 1 1 2 0.417412 0.348716 0.147965 \n", "6017 3 1 1 0.563506 0.069594 0.062571 \n", "6018 1 1 1 0.758497 0.058057 0.044504 \n", "\n", " Seats Price \n", "0 5.0 1.75 \n", "1 5.0 12.50 \n", "2 5.0 4.50 \n", "3 7.0 6.00 \n", "4 5.0 17.74 \n", "... ... ... \n", "6014 5.0 4.75 \n", "6015 5.0 4.00 \n", "6016 8.0 2.90 \n", "6017 5.0 2.65 \n", "6018 5.0 2.50 \n", "\n", "[5872 rows x 12 columns]" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#fazer com que o modelo entenda melhor a grandeza dos dados, nesse caso vamos fazer os dados listados terem um \"range\" de 0 a 1\n", "\n", "from sklearn.preprocessing import MinMaxScaler\n", "\n", "scaler = MinMaxScaler()\n", "\n", "car_train[['Power', 'Engine', 'Mileage', 'Kilometers_Driven']] = scaler.fit_transform(car_train[['Power', 'Engine', 'Mileage', 'Kilometers_Driven']])\n", "\n", "car_train\n", "\n", "# Existem variáveis que não fazem sentido normalizar - qualificações " ] }, { "cell_type": "markdown", "metadata": { "id": "Z1-ARAkAxyP9" }, "source": [ "## **Parte 2 - Modelagem**" ] }, { "cell_type": "markdown", "metadata": { "id": "0GVYpd78xyP9" }, "source": [ "### Treino e teste\n" ] }, { "cell_type": "markdown", "metadata": { "id": "XvFtilbu1Sdt" }, "source": [ "\n", "O primeiro passo para criar qualquer modelo de aprendizado de máquina é dividir os dados em conjuntos de 'treinamento', 'teste' e 'validação'. O conjunto de validação é opcional, mas muito importante se você planeja implantar o modelo na vida real.\n", "\n", "Mas por que a validação é importante?\n", "\n", "O conjunto 'train' é usado para treinamento, o conjunto 'test' é usado para executar as previsões e é com essas previsões que os hiperparâmetros são ajustados e o modelo é treinado novamente para melhor precisão. Assim, você pode ver que, às vezes, se você ajustar esses parâmetros, o modelo pode ser tendencioso para fornecer uma boa previsão apenas no conjunto de teste e não em qualquer conjunto geral." ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "id": "IalLFvHFxyP-", "outputId": "effd50ca-deb9-4338-8182-ac3d21a7232a" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PowerEngineTransmissionYearMileage
26920.2963100.255117020110.676506
700.8858880.778191020080.253429
59580.1224800.162635120150.769231
17980.0905290.106624120160.655933
34150.0756940.116115120160.751342
..................
50590.1032710.116115120170.724508
33510.1061240.143655120140.685748
16990.2069230.348902120070.324985
26830.0624570.069594120170.688730
28100.0624570.069594120160.611509
\n", "

4110 rows × 5 columns

\n", "
" ], "text/plain": [ " Power Engine Transmission Year Mileage\n", "2692 0.296310 0.255117 0 2011 0.676506\n", "70 0.885888 0.778191 0 2008 0.253429\n", "5958 0.122480 0.162635 1 2015 0.769231\n", "1798 0.090529 0.106624 1 2016 0.655933\n", "3415 0.075694 0.116115 1 2016 0.751342\n", "... ... ... ... ... ...\n", "5059 0.103271 0.116115 1 2017 0.724508\n", "3351 0.106124 0.143655 1 2014 0.685748\n", "1699 0.206923 0.348902 1 2007 0.324985\n", "2683 0.062457 0.069594 1 2017 0.688730\n", "2810 0.062457 0.069594 1 2016 0.611509\n", "\n", "[4110 rows x 5 columns]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "2692 10.30\n", "70 14.50\n", "5958 4.68\n", "1798 5.10\n", "3415 5.63\n", " ... \n", "5059 9.05\n", "3351 4.50\n", "1699 3.00\n", "2683 4.99\n", "2810 3.60\n", "Name: Price, Length: 4110, dtype: float64" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from sklearn.model_selection import train_test_split\n", "#Vamos treinar a máquina \n", "# Depois vamos mostrar apenas as variáveis para a máquina tentar predizer essas variáveis - Depois é possível comparar com a base real\n", "# Validação - usar o modelo em base de dados que não foram treinadas (overfeeting (vai muito bem nessa base de dados) e underfeeting (poucos dados) )\n", "\n", "\n", "#Definição de variáveis\n", "X, y = car_train[['Power', 'Engine', 'Transmission', 'Year', 'Mileage']], car_train['Price']\n", "# X, y = car_train[['Power','Transmission']], car_train['Price']\n", "# X, y = car_train[['Year','Kilometers_Driven']], car_train['Price']\n", "\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0, train_size= 0.7) #vai randomizar a base de dados e vai fazer \n", " # um corte pra base de treino (pode ser determinado) - \n", " # Não pode usar em time series \n", " # (por que existe uma tensência durante o tempo)\n", "\n", "\n", "display(X_train,y_train)" ] }, { "cell_type": "markdown", "metadata": { "id": "TssxaE4HxyP_" }, "source": [ "### Escolha do modelo - Nosso modelos: regressão boosted" ] }, { "cell_type": "markdown", "metadata": { "id": "TO8V81Xf1ODO" }, "source": [ "\n", "**Machine Learning Algorithms Cheat Sheet**\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "id": "NpAOLVn8xyP_" }, "source": [ "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "ovMcgsm2xyQA" }, "source": [ "Para esse exercício, usarei uma regressão de Boosted Decision Tree, pois é um modelo um pouco mais complexo que tem um tempo de treinamento pequeno. Esse algorítmo funciona da seguinte forma: Junta árvores de decisões \n", "\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "id": "ZBVoGW9zxyQA" }, "outputs": [], "source": [ "from sklearn.ensemble import GradientBoostingRegressor\n", "\n", "reg = GradientBoostingRegressor(n_estimators = 300, learning_rate = 0.5, max_depth=100) #mudanos o número de estimadores e aumentamos as interações \n", "reg = reg.fit(X_train, y_train) # fit é o treino - é usado para treinar o modelo usando os dados de treinamento fornecidos. \n", " # Durante o treinamento, o modelo ajusta seus parâmetros internos para minimizar a diferença entre as previsões \n", " # feitas pelo modelo e os valores reais observados nos dados de treinamento.\n", "\n", "y_pred = reg.predict(X_test)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "lGVMc2pLxyQB", "outputId": "3c5ff076-e74a-41a6-a5db-00551d0344bc" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0
Price
0.851.050
10.9415.250
3.002.250
16.0017.250
4.953.000
......
3.402.745
30.3722.660
10.469.872
3.002.000
32.9031.150
\n", "

1762 rows × 1 columns

\n", "
" ], "text/plain": [ " 0\n", "Price \n", "0.85 1.050\n", "10.94 15.250\n", "3.00 2.250\n", "16.00 17.250\n", "4.95 3.000\n", "... ...\n", "3.40 2.745\n", "30.37 22.660\n", "10.46 9.872\n", "3.00 2.000\n", "32.90 31.150\n", "\n", "[1762 rows x 1 columns]" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.DataFrame(y_pred, y_test) #esquerda o preço real / direira é a nossa predição " ] }, { "cell_type": "markdown", "metadata": { "id": "ArAjPWHXxyQB" }, "source": [ "### Validação\n" ] }, { "cell_type": "markdown", "metadata": { "id": "YZVcTeNZ04NC" }, "source": [ "\n", "Com o modelo treinado, agora precisamos verificar e validar o modelo de acordo com a sua acurácia.\n", "\n", "Como se trata de um problema de REGRESSÃO, devemos obrigatoriamente utilizar métricas de validação adequadas para REGRESSÕES:\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "9RujeVFPxyQC", "outputId": "3c5df826-66a7-4289-d03d-da2e2d72e63c" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Mean absolute error (MAE) = 1.93\n", "Mean absolute percentage error (MAPE) = 20.05%\n", "Mean squared error (MSE) = 23.34\n", "Root mean squared error (RMSE) = 4.83\n" ] } ], "source": [ "import sklearn.metrics as sm\n", "\n", "#Métricas simples\n", "\n", "print(\"Mean absolute error (MAE) =\", round(sm.mean_absolute_error(y_test, y_pred), 2)) #Erro médio absoluto \n", "print(f\"Mean absolute percentage error (MAPE) = {round(sm.mean_absolute_percentage_error(y_test, y_pred), 4): 0.2%}\") #Erro médio absoluto em %\n", "print(\"Mean squared error (MSE) =\", round(sm.mean_squared_error(y_test, y_pred), 2)) #Erro médio quadrado \n", "print(f'Root mean squared error (RMSE) = {round(sm.mean_squared_error(y_test, y_pred, squared= False),2)}') #Raiz quadrada da média dos erros - Quanto menor menlhor \n", " # mede a média das diferenças quadradas entre os valores \n", " # observados (reais) e os valores previstos pelo modelo." ] }, { "cell_type": "markdown", "metadata": { "id": "A_R-RrSyxyQC" }, "source": [ "Para testar se o nosso modelo está overfittado, vamos utilizar a técnica de KFold para analisar a performance do modelo em diversas situações de treino e teste (não pode aplicar para time series):\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "id": "_mhr_mhXxyQD", "outputId": "0816b1b3-0b9c-4700-ba1c-b6fd99b131cd" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Acurácia da validação cruzada K-Fold: 4.675 +/- 0.425\n" ] } ], "source": [ "from sklearn.model_selection import cross_val_score\n", "\n", "#Validação por KFold\n", "\n", "scores = cross_val_score(reg, X=X_train, y=y_train, cv=5, n_jobs=1, scoring= 'neg_root_mean_squared_error') #cv - Número de Folds, dados divididos em 5 partes \n", " # n_jobs = o calculo será executado em apenas um núcleo \n", " # RMSE - erro médio quadratico como forma de avaliação \n", "\n", "print('Acurácia da validação cruzada K-Fold: %.3f +/- %.3f' % (-np.mean(scores),np.std(scores)))\n", "\n", "#Erro médio quadrado +/-\n", "# Resultado - A média do RMSE através das 5 iterações da validação cruzada é aproximadamente 4.675.\n", "# O desvio padrão do RMSE é 0.425.\n", "# O desvio padrão de 0.425 em comparação com o valor médio de 4.675 é relativamente pequeno, \n", "# sugerindo que o modelo é consistente entre as diferentes iterações da validação cruzada. \n", "# Isso é um bom sinal e indica que o modelo não varia muito entre os diferentes folds.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "j1ZWihiXxyQE" }, "source": [ "### Ensemble" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " Técnica de aprendizado de máquina que combina as previsões de múltiplos modelos individuais para melhorar a precisão e a robustez das previsões. A ideia por trás dos métodos ensemble é que a combinação de vários modelos pode capturar uma gama mais ampla de padrões e variações nos dados, reduzindo assim o risco de overfitting e melhorando a performance geral.\n", "\n", " 1- Bagging (Bootstrap Aggregating):\n", " \n", " a) Random Forest: Um dos exemplos mais conhecidos de bagging, onde múltiplas árvores de decisão são treinadas em diferentes subconjuntos dos dados de treinamento (obtidos por bootstrap) e suas previsões são combinadas (por votação para classificação ou média para regressão).\n", " \n", " 2- Boosting:\n", "\n", " a) Gradient Boosting Machines (GBM): Modelos são treinados sequencialmente, com cada novo modelo corrigindo os erros dos modelos anteriores. Exemplos populares incluem XGBoost, LightGBM, e CatBoost.\n", "\n", " b) AdaBoost: Um método que ajusta o peso das observações com base no erro dos modelos anteriores, focando mais em observações difíceis.\n", " \n", " 3- Stacking:\n", " \n", " a) Modelos individuais (de diferentes tipos ou parâmetros) são treinados e suas previsões são usadas como entradas para um modelo final (meta-modelo), que aprende a melhor combinação dessas previsões.\n", " \n", " 4- Voting:Para problemas de classificação, várias previsões de modelos são combinadas por votação majoritária (votação simples) ou ponderada (votação ponderada) para decidir a classe final" ] }, { "cell_type": "markdown", "metadata": { "id": "wV3zt5Sc0yxf" }, "source": [ "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "rS3tvX6AxyQF", "outputId": "710e0fa6-77ba-453c-e169-110cff68fd7d" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "KNeighbors 4.629 (0.175)\n", "DecisionTree 4.709 (0.559)\n", "XGBoost 3.758 (0.385)\n", "GradientBoosting 4.691 (0.408)\n", "Stacking 3.742 (0.357)\n" ] } ], "source": [ "from sklearn.tree import DecisionTreeRegressor\n", "from sklearn.neighbors import KNeighborsRegressor\n", "from sklearn.linear_model import LinearRegression\n", "from sklearn.ensemble import StackingRegressor\n", "import xgboost as xgb\n", "\n", "from sklearn.model_selection import KFold\n", "\n", "from sklearn.utils._testing import ignore_warnings\n", "from sklearn.exceptions import ConvergenceWarning\n", "\n", "# ensemble do modelo por stacking\n", "@ignore_warnings(category=ConvergenceWarning)\n", "\n", "def get_stacking():\n", "\t# modelos base\n", "\tlevel0 = list()\n", "\tlevel0.append(('KNeighbors', KNeighborsRegressor()))\n", "\tlevel0.append(('XGBoost', xgb.XGBRegressor()))\n", "\tlevel0.append(('Decision', DecisionTreeRegressor()))\n", "\tlevel0.append(('GradientBoosting', GradientBoostingRegressor()))\n", "\t# modelo meta learner\n", "\tlevel1 = LinearRegression()\n", "\tmodel = StackingRegressor(estimators=level0, final_estimator=level1, cv=5)\n", "\treturn model\n", "\n", "# modelos para avaliar\n", "def get_models():\n", "\tmodels = dict()\n", "\tmodels['KNeighbors'] = KNeighborsRegressor()\n", "\tmodels['DecisionTree'] = DecisionTreeRegressor()\n", "\tmodels['XGBoost'] = xgb.XGBRegressor()\n", "\tmodels['GradientBoosting'] = GradientBoostingRegressor(n_estimators = 300, learning_rate = 0.5, max_depth=100)\n", "\tmodels['Stacking'] = get_stacking()\n", "\treturn models\n", "\n", "# avaliação dos modelos por cross-validation\n", "def evaluate_model(model, X, y):\n", "\tscores = cross_val_score(model, X, y, scoring='neg_root_mean_squared_error', cv=5, n_jobs=-1, error_score='raise')\n", "\treturn scores\n", "\n", "models = get_models()\n", "\n", "results, names = list(), list()\n", "for name, model in models.items():\n", "\tscores = evaluate_model(model, X_train, y_train)\n", "\tresults.append(scores)\n", "\tnames.append(name)\n", "\tprint('%s %.3f (%.3f)' % (name, -np.mean(scores), np.std(scores)))\n", " \n", "# os resultados da avaliação dos modelos por cross-validation indicam a performance de cada modelo na tarefa de regressão.\n", "# métrica de avaliação: RMSE " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Interpretação\n", "\n", "1- O XGBoost apresenta o menor RMSE médio entre os modelos individuais, indicando uma boa performance na previsão.\n", "\n", "2- O modelo Stacking também tem um RMSE médio competitivo, sugerindo que a combinação dos modelos base está ajudando a melhorar a precisão das previsões.\n", "\n", "3- Os modelos KNeighbors e DecisionTree têm RMSEs médios mais altos, indicando uma performance inferior na tarefa de previsão em comparação com o XGBoost e o Stacking.\n", "\n", "4- O desvio padrão em todos os modelos é relativamente baixo, o que sugere uma consistência razoável nas previsões entre as dobras de cross-validation." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "GNMnlGTtxyQG" }, "outputs": [], "source": [ "model = model.fit(X_train, y_train)\n", "\n", "y_pred = model.predict(X_test)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "7U21wlrOxyQH", "outputId": "b9485758-b25f-4457-f15b-ba3774282111" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Mean absolute error (MAE) = 1.7\n", "Mean absolute percentage error (MAPE) = 17.45%\n", "Mean squared error (MSE) = 18.92\n", "Root mean squared error (RMSE) = 4.35\n" ] } ], "source": [ "#Métricas simples\n", "\n", "print(\"Mean absolute error (MAE) =\", round(sm.mean_absolute_error(y_test, y_pred), 2))\n", "print(f\"Mean absolute percentage error (MAPE) = {round(sm.mean_absolute_percentage_error(y_test, y_pred), 4): 0.2%}\")\n", "print(\"Mean squared error (MSE) =\", round(sm.mean_squared_error(y_test, y_pred), 2))\n", "print(f'Root mean squared error (RMSE) = {round(sm.mean_squared_error(y_test, y_pred, squared= False),2)}')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# errou menos do que o último modelo " ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "2eaf2605f86d6c7bf8701796461e0310715783929ef3cb9e7757643455c26c87" } } }, "nbformat": 4, "nbformat_minor": 0 }